package pub.tbc.api.handler.old;

import com.google.common.base.Charsets;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import lombok.extern.slf4j.Slf4j;
import pub.tbc.api.invoker.Invoker;
import pub.tbc.api.invoker.InvokerFactory;

import static io.netty.handler.codec.http.HttpHeaderNames.*;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;


/**
 * netty处理调最后一环，请求其它系统；
 * 需要：协议转换组件、具体协议的请求转发组件
 *
 * @author tbc on 2017/3/3 13:10:53.
 */
@Slf4j
public class InvokerHandler extends ChannelInboundHandlerAdapter {
    // 具体的的调用器应该按配置生成（约定默认值），交由专门的工厂处理
    private Invoker invoker = InvokerFactory.getInvoker();

    private int tempInt = 0;


    private String readContent(ByteBuf buf) {
        byte[] bytes = new byte[buf.readableBytes()];
        buf.readBytes(bytes);
        return new String(bytes, Charsets.UTF_8);
    }

    @Override
    public void channelRead(ChannelHandlerContext context, Object msg) throws Exception {
        log.debug("service invoker : {}", invoker.getClass().getName());
        tempInt++;
        log.debug("\ntempInt => {}\nhandlerHashCode=> {}", tempInt, hashCode());
        if (!(msg instanceof FullHttpRequest)) {
            System.out.println("===================> " + msg);
            return;
        }
        FullHttpRequest request = (FullHttpRequest) msg;
        invoker.invoke(context, request);

        System.out.println(request.method());
        System.out.println(request.uri());
        System.out.println(readContent(request.content()));

        String res = "Hi~Netty, I am OK\r\n";

        FullHttpResponse response = new DefaultFullHttpResponse(
                HTTP_1_1,
                OK,
                Unpooled.wrappedBuffer(res.getBytes("UTF-8"))
        );
        response.headers()
                .set(CONTENT_TYPE, "text/plain")
                .set(CONTENT_LENGTH, response.content().readableBytes());
        if (HttpUtil.isKeepAlive(request)) {
            response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE);
        }
        ChannelFuture future = context.writeAndFlush(response);

        if (!HttpUtil.isKeepAlive(request)) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
        log.error("发生异常： {}", cause.getMessage());
        context.close();
        context.fireChannelRead(cause);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        System.out.println("[断开连接]channelInactive...");
    }

    @Override
    public void channelActive(ChannelHandlerContext context) {
        System.out.println("[建立连接]channelActive...");
    }

}
